package com.ty.skysystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ty.common.constant.FinishedStateEnum;
import com.ty.common.utils.PageUtils;
import com.ty.common.utils.Query;
import com.ty.skysystem.dao.CarriersDao;
import com.ty.skysystem.dao.GoodsDao;
import com.ty.skysystem.dao.SchedulingDao;
import com.ty.skysystem.entity.CarriersEntity;
import com.ty.skysystem.entity.GoodsEntity;
import com.ty.skysystem.entity.SchedulingEntity;
import com.ty.skysystem.entity.to.CarriersSchedulingEntityTo;
import com.ty.skysystem.entity.vo.CarriersGoodsVo;
import com.ty.skysystem.service.CarriersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

@Service("carriersService")
@Slf4j
public class CarriersServiceImpl extends ServiceImpl<CarriersDao, CarriersEntity>
    implements CarriersService {

  @Autowired private CarriersDao carriersDao;
  @Autowired private GoodsDao goodsDao;
  @Autowired private SchedulingDao schedulingDao;

  /**
   * 查询全部承运单信息
   *
   * @param params
   * @return
   */
  @Override
  public PageUtils queryPage(Map<String, Object> params) {
    IPage<CarriersEntity> page =
        this.page(
            new Query<CarriersEntity>().getPage(params),
            new QueryWrapper<CarriersEntity>()
                .select(CarriersEntity.class, e -> !"is_deleted".equals(e.getColumn())));
    return new PageUtils(page);
  }

  /**
   * 查询全部未调度的承运单 待调度的
   *
   * @param params
   * @return
   */
  @Override
  public PageUtils queryPageUnscheduledCarriers(Map<String, Object> params) {
    IPage<CarriersEntity> page =
        this.page(
            new Query<CarriersEntity>().getPage(params),
            new QueryWrapper<CarriersEntity>()
                .eq("finished_state", FinishedStateEnum.TO_BE_SCHEDULED.getState())
                .select(CarriersEntity.class, e -> !"is_deleted".equals(e.getColumn())));
    return new PageUtils(page);
  }

  /**
   * 新增承运任务 操作: 承运单 货物详情
   *
   * @param carriersGoodsVo
   * @return
   */
  @Transactional(rollbackFor = {RuntimeException.class})
  @Override
  public boolean saveCarriersGoods(CarriersGoodsVo carriersGoodsVo) {

    CarriersEntity carriersEntity = new CarriersEntity();
    carriersEntity.setSendCompany(carriersGoodsVo.getSendCompany());
    carriersEntity.setSendAddress(carriersGoodsVo.getSendAddress());
    carriersEntity.setSendLinkman(carriersGoodsVo.getSendLinkman());
    carriersEntity.setSendPhone(carriersGoodsVo.getSendPhone());
    carriersEntity.setReceiveCompany(carriersGoodsVo.getReceiveCompany());
    carriersEntity.setReceiveAddress(carriersGoodsVo.getReceiveAddress());
    carriersEntity.setReceiveLinkman(carriersGoodsVo.getReceiveLinkman());
    carriersEntity.setReceivePhone(carriersGoodsVo.getReceivePhone());
    carriersEntity.setInsuranceCost(carriersGoodsVo.getInsuranceCost());
    carriersEntity.setTransportCost(carriersGoodsVo.getTransportCost());
    carriersEntity.setOtherCost(carriersGoodsVo.getOtherCost());
    carriersEntity.setTotalCost(carriersGoodsVo.getTotalCost());
    carriersEntity.setRemark(carriersGoodsVo.getRemark());
    int i = carriersDao.insert(carriersEntity);
    GoodsEntity goodsEntity = new GoodsEntity();
    goodsEntity.setGoodsName(carriersGoodsVo.getGoodsName());
    goodsEntity.setAmount(carriersGoodsVo.getAmount());
    goodsEntity.setWeight(carriersGoodsVo.getWeight());
    goodsEntity.setVolume(carriersGoodsVo.getVolume());
    goodsEntity.setCarriersId(carriersEntity.getCarriersId());
    int j = goodsDao.insert(goodsEntity);
    if (i <= 0 || j <= 0) {
      throw new RuntimeException("网络异常,请重试");
    }
    return true;
  }

  /** 查询全部已调度的承运单信息 */
  @Override
  public PageUtils queryPageScheduled(Map<String, Object> params) {
    IPage<CarriersEntity> page =
        this.page(
            new Query<CarriersEntity>().getPage(params),
            new QueryWrapper<CarriersEntity>()
                .eq("finished_state", FinishedStateEnum.SCHEDULED.getState())
                .select(CarriersEntity.class, e -> !"is_deleted".equals(e.getColumn())));
    return new PageUtils(page);
  }

  /** 根据ID数组修改承运单状态 */
  @Override
  public boolean updateStateByIds(Long[] carriersIds) {
    ArrayList<CarriersEntity> list = new ArrayList<>();
    Arrays.stream(carriersIds)
        .forEach(
            item -> {
              CarriersEntity carriersEntity = new CarriersEntity();
              carriersEntity.setCarriersId(item);
              carriersEntity.setReceiveDate(new Date());
              carriersEntity.setFinishedState(FinishedStateEnum.RECEIVED.getState());
              list.add(carriersEntity);
            });
    return this.updateBatchById(list);
  }

  /**
   * 查询出已接收承运单
   *
   * @param params
   * @return
   */
  @Override
  public PageUtils receiveCarriers(Map<String, Object> params) {
    IPage<CarriersEntity> page =
        this.page(
            new Query<CarriersEntity>().getPage(params),
            new QueryWrapper<CarriersEntity>()
                .eq("finished_state", FinishedStateEnum.RECEIVED.getState())
                .select(CarriersEntity.class, e -> !"is_deleted".equals(e.getColumn())));

    return new PageUtils(page);
  }
  /**
   * 录入成本 对成本进行计算
   *
   * <p>对调度任务信息表的费用核算 合计成本 = 油费 + 过桥费 + 罚款 + 其他费用
   *
   * <p>对承运单进行费用核算 合计成本 = 保险费 + 运费 + 其他费用
   */
  @Transactional(rollbackFor = {RuntimeException.class})
  @Override
  public BigDecimal settleAccount(Integer carriersId) {
    // 连表查询承运单和对应的调度任务表
    CarriersSchedulingEntityTo carriersSchedulingEntityTo =
        carriersDao.selectCarriersSchedulingById(carriersId);
    // 对调度任务进行结算, 添加到合计成本
    SchedulingEntity schedulingEntity = new SchedulingEntity();
    schedulingEntity.setSchedulingId(carriersSchedulingEntityTo.getSchedulingId());
    if (carriersSchedulingEntityTo.getOilCostScheduling() == null)
      carriersSchedulingEntityTo.setOilCostScheduling(BigDecimal.ZERO);
    if (carriersSchedulingEntityTo.getTollScheduling() == null)
      carriersSchedulingEntityTo.setTollScheduling(BigDecimal.ZERO);
    if (carriersSchedulingEntityTo.getFineScheduling() == null)
      carriersSchedulingEntityTo.setFineScheduling(BigDecimal.ZERO);
    if (carriersSchedulingEntityTo.getOtherCostScheduling() == null)
      carriersSchedulingEntityTo.setOtherCostScheduling(BigDecimal.ZERO);

    schedulingEntity.setTotalCost(
        carriersSchedulingEntityTo
            .getOilCostScheduling()
            .add(carriersSchedulingEntityTo.getTollScheduling())
            .add(carriersSchedulingEntityTo.getFineScheduling())
            .add(carriersSchedulingEntityTo.getOtherCostScheduling()));
    int i = schedulingDao.updateById(schedulingEntity);

    // 对承运单进行结算 修改订单状态和合计成本
    CarriersEntity carriersEntity = new CarriersEntity();
    carriersEntity.setCarriersId(carriersSchedulingEntityTo.getCarriersId());
    carriersEntity.setFinishedState(FinishedStateEnum.SETTLE_ACCOUNTS.getState());
    if (carriersSchedulingEntityTo.getInsuranceCost() == null)
      carriersSchedulingEntityTo.setInsuranceCost(BigDecimal.ZERO);
    if (carriersSchedulingEntityTo.getTransportCost() == null)
      carriersSchedulingEntityTo.setTransportCost(BigDecimal.ZERO);
    if (carriersSchedulingEntityTo.getOtherCost() == null)
      carriersSchedulingEntityTo.setOtherCost(BigDecimal.ZERO);
    carriersEntity.setTotalCost(
        carriersSchedulingEntityTo
            .getInsuranceCost()
            .add(carriersSchedulingEntityTo.getTransportCost())
            .add(carriersSchedulingEntityTo.getOtherCost()));

    int j = carriersDao.updateById(carriersEntity);
    if (i <= 0 || j <= 0) throw new RuntimeException("网络异常, 请重试");
    return carriersEntity.getTotalCost();
  }
  /** 查询已结算和已接收的承运任务 */
  @Override
  public PageUtils settleAccountsReceiveCarriers(Map<String, Object> params) {
    IPage<CarriersEntity> page =
        this.page(
            new Query<CarriersEntity>().getPage(params),
            new QueryWrapper<CarriersEntity>()
                .in(
                    "finished_state",
                    FinishedStateEnum.RECEIVED.getState(),
                    FinishedStateEnum.SETTLE_ACCOUNTS.getState())
                .select(CarriersEntity.class, e -> !"is_deleted".equals(e.getColumn())));

    return new PageUtils(page);
  }

  @Override
  public PageUtils accountingForTransportationCosts(Integer page, Integer limit, String teamName) {
    IPage<CarriersEntity> nameEntityToIPage = baseMapper.accountingForTransportationCosts(new Page<CarriersEntity>(page, limit), teamName);
    return new PageUtils(nameEntityToIPage);
  }

  /**
   * 查询全部历史承运信息 已结算的
   *
   * @param params
   * @return
   */
  @Override
  public PageUtils queryPageHistoryCarriers(Map<String, Object> params) {
    IPage<CarriersEntity> page =
        this.page(
            new Query<CarriersEntity>().getPage(params),
            new QueryWrapper<CarriersEntity>()
                .eq("finished_state", FinishedStateEnum.SETTLE_ACCOUNTS.getState())
                .select(CarriersEntity.class, e -> !"is_deleted".equals(e.getColumn())));
    return new PageUtils(page);
  }
}
